#include "alarmengine.h"
#include "../utils/logger.h"
#include <QDebug>

AlarmEngine::AlarmEngine(DBManager *dbManager, QObject *parent)
    : QObject(parent), m_dbManager(dbManager), m_enabled(true), m_totalAlarmCount(0)
{
    m_recoveryCheckTimer = new QTimer(this);
    m_recoveryCheckTimer->setInterval(5000); // 每5秒检查一次恢复
    connect(m_recoveryCheckTimer, &QTimer::timeout, this, &AlarmEngine::checkAlarmRecovery);

    Logger::instance()->info("报警引擎初始化完成");
}

AlarmEngine::~AlarmEngine()
{
    stop();
    Logger::instance()->info("报警引擎已销毁");
}

void AlarmEngine::setThreshold(const AlarmThreshold &threshold)
{
    m_threshold = threshold;
    Logger::instance()->info(QString("报警阈值已更新 - 电压跌落: %1V, 过压: %2V, 欠压: %3V, 过流: %4A")
                                 .arg(threshold.voltageDropThreshold)
                                 .arg(threshold.overVoltageThreshold)
                                 .arg(threshold.underVoltageThreshold)
                                 .arg(threshold.overCurrentThreshold));
}

void AlarmEngine::start()
{
    if (m_enabled)
    {
        m_recoveryCheckTimer->start();
        Logger::instance()->info("报警引擎已启动");
    }
}

void AlarmEngine::stop()
{
    m_recoveryCheckTimer->stop();
    Logger::instance()->info("报警引擎已停止");
}

void AlarmEngine::setEnabled(bool enabled)
{
    if (m_enabled != enabled)
    {
        m_enabled = enabled;
        emit enabledChanged();

        if (m_enabled)
        {
            start();
        }
        else
        {
            stop();
        }

        Logger::instance()->info(QString("报警引擎%1").arg(enabled ? "已启用" : "已禁用"));
    }
}

void AlarmEngine::addMeter(Meter *meter)
{
    if (!meter)
        return;

    int meterId = meter->meterId();
    if (m_meters.contains(meterId))
    {
        Logger::instance()->warning(QString("电表 %1 已在监控列表中").arg(meterId));
        return;
    }

    m_meters.insert(meterId, meter);

    // 连接电表信号
    connect(meter, &Meter::dataUpdated, this, &AlarmEngine::onMeterDataUpdated);
    connect(meter, &Meter::onlineChanged, this, [this, meter]()
            {
        if (!meter->isOnline()) {
            onMeterOffline();
        } });

    Logger::instance()->debug(QString("报警引擎：添加电表 %1 到监控列表").arg(meterId));
}

void AlarmEngine::checkMeter(Meter *meter)
{
    if (!m_enabled || !meter || !meter->isOnline())
    {
        return;
    }

    checkVoltageAlarms(meter);
    checkCurrentAlarms(meter);
}

int AlarmEngine::activeAlarmCount() const
{
    return m_activeAlarms.size();
}

QVector<AlarmEvent> AlarmEngine::getActiveAlarms() const
{
    QVector<AlarmEvent> alarms;
    for (const AlarmEvent &event : m_activeAlarms.values())
    {
        alarms.append(event);
    }
    return alarms;
}

bool AlarmEngine::acknowledgeAlarm(int alarmId)
{
    // 在数据库中标记为已确认
    bool success = m_dbManager->acknowledgeAlarm(alarmId);

    if (success)
    {
        // 更新内存中的状态
        for (auto it = m_activeAlarms.begin(); it != m_activeAlarms.end(); ++it)
        {
            if (it.value().alarmId == alarmId)
            {
                it.value().acknowledged = true;
                break;
            }
        }

        Logger::instance()->info(QString("报警 %1 已确认").arg(alarmId));
    }

    return success;
}

QString AlarmEngine::getAlarmTypeName(AlarmType type)
{
    switch (type)
    {
    case AlarmType::VoltageDropA:
        return "A相电压跌落";
    case AlarmType::VoltageDropB:
        return "B相电压跌落";
    case AlarmType::VoltageDropC:
        return "C相电压跌落";
    case AlarmType::OverVoltageA:
        return "A相过压";
    case AlarmType::OverVoltageB:
        return "B相过压";
    case AlarmType::OverVoltageC:
        return "C相过压";
    case AlarmType::UnderVoltageA:
        return "A相欠压";
    case AlarmType::UnderVoltageB:
        return "B相欠压";
    case AlarmType::UnderVoltageC:
        return "C相欠压";
    case AlarmType::OverCurrentA:
        return "A相过流";
    case AlarmType::OverCurrentB:
        return "B相过流";
    case AlarmType::OverCurrentC:
        return "C相过流";
    case AlarmType::DeviceOffline:
        return "设备离线";
    default:
        return "未知报警";
    }
}

void AlarmEngine::onMeterDataUpdated()
{
    if (!m_enabled)
        return;

    Meter *meter = qobject_cast<Meter *>(sender());
    if (meter)
    {
        checkMeter(meter);
    }
}

void AlarmEngine::onMeterOffline()
{
    if (!m_enabled)
        return;

    Meter *meter = qobject_cast<Meter *>(sender());
    if (meter && !meter->isOnline())
    {
        // 触发设备离线报警
        triggerAlarm(meter, AlarmType::DeviceOffline, 0, 0);
    }
}

void AlarmEngine::checkAlarmRecovery()
{
    if (!m_enabled)
        return;

    QStringList recoveredKeys;

    for (auto it = m_activeAlarms.begin(); it != m_activeAlarms.end(); ++it)
    {
        const AlarmEvent &event = it.value();
        Meter *meter = m_meters.value(event.meterId, nullptr);

        if (!meter || !meter->isOnline())
        {
            continue;
        }

        bool recovered = false;

        // 检查各类报警是否恢复
        switch (event.type)
        {
        case AlarmType::VoltageDropA:
        case AlarmType::UnderVoltageA:
            recovered = (meter->ua() >= m_threshold.underVoltageThreshold + 2.0); // 加2V滞回
            break;
        case AlarmType::VoltageDropB:
        case AlarmType::UnderVoltageB:
            recovered = (meter->ub() >= m_threshold.underVoltageThreshold + 2.0);
            break;
        case AlarmType::VoltageDropC:
        case AlarmType::UnderVoltageC:
            recovered = (meter->uc() >= m_threshold.underVoltageThreshold + 2.0);
            break;
        case AlarmType::OverVoltageA:
            recovered = (meter->ua() <= m_threshold.overVoltageThreshold - 2.0);
            break;
        case AlarmType::OverVoltageB:
            recovered = (meter->ub() <= m_threshold.overVoltageThreshold - 2.0);
            break;
        case AlarmType::OverVoltageC:
            recovered = (meter->uc() <= m_threshold.overVoltageThreshold - 2.0);
            break;
        case AlarmType::OverCurrentA:
            recovered = (meter->ia() <= m_threshold.overCurrentThreshold - 2.0);
            break;
        case AlarmType::OverCurrentB:
            recovered = (meter->ib() <= m_threshold.overCurrentThreshold - 2.0);
            break;
        case AlarmType::OverCurrentC:
            recovered = (meter->ic() <= m_threshold.overCurrentThreshold - 2.0);
            break;
        case AlarmType::DeviceOffline:
            recovered = meter->isOnline();
            break;
        }

        if (recovered)
        {
            recoveredKeys.append(it.key());
        }
    }

    // 恢复报警
    for (const QString &key : recoveredKeys)
    {
        recoverAlarm(key);
    }
}

void AlarmEngine::checkVoltageAlarms(Meter *meter)
{
    if (!meter)
        return;

    double ua = meter->ua();
    double ub = meter->ub();
    double uc = meter->uc();

    // 检查A相电压
    if (ua > 0)
    {
        if (ua < m_threshold.voltageDropThreshold)
        {
            triggerAlarm(meter, AlarmType::VoltageDropA, ua, m_threshold.voltageDropThreshold);
        }
        else if (ua < m_threshold.underVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::UnderVoltageA, ua, m_threshold.underVoltageThreshold);
        }
        else if (ua > m_threshold.overVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::OverVoltageA, ua, m_threshold.overVoltageThreshold);
        }
        else
        {
            // 正常，检查是否需要恢复
            QString key1 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::VoltageDropA));
            QString key2 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::UnderVoltageA));
            QString key3 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverVoltageA));
            if (m_activeAlarms.contains(key1))
                recoverAlarm(key1);
            if (m_activeAlarms.contains(key2))
                recoverAlarm(key2);
            if (m_activeAlarms.contains(key3))
                recoverAlarm(key3);
        }
    }

    // 检查B相电压
    if (ub > 0)
    {
        if (ub < m_threshold.voltageDropThreshold)
        {
            triggerAlarm(meter, AlarmType::VoltageDropB, ub, m_threshold.voltageDropThreshold);
        }
        else if (ub < m_threshold.underVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::UnderVoltageB, ub, m_threshold.underVoltageThreshold);
        }
        else if (ub > m_threshold.overVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::OverVoltageB, ub, m_threshold.overVoltageThreshold);
        }
        else
        {
            QString key1 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::VoltageDropB));
            QString key2 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::UnderVoltageB));
            QString key3 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverVoltageB));
            if (m_activeAlarms.contains(key1))
                recoverAlarm(key1);
            if (m_activeAlarms.contains(key2))
                recoverAlarm(key2);
            if (m_activeAlarms.contains(key3))
                recoverAlarm(key3);
        }
    }

    // 检查C相电压
    if (uc > 0)
    {
        if (uc < m_threshold.voltageDropThreshold)
        {
            triggerAlarm(meter, AlarmType::VoltageDropC, uc, m_threshold.voltageDropThreshold);
        }
        else if (uc < m_threshold.underVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::UnderVoltageC, uc, m_threshold.underVoltageThreshold);
        }
        else if (uc > m_threshold.overVoltageThreshold)
        {
            triggerAlarm(meter, AlarmType::OverVoltageC, uc, m_threshold.overVoltageThreshold);
        }
        else
        {
            QString key1 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::VoltageDropC));
            QString key2 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::UnderVoltageC));
            QString key3 = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverVoltageC));
            if (m_activeAlarms.contains(key1))
                recoverAlarm(key1);
            if (m_activeAlarms.contains(key2))
                recoverAlarm(key2);
            if (m_activeAlarms.contains(key3))
                recoverAlarm(key3);
        }
    }
}

void AlarmEngine::checkCurrentAlarms(Meter *meter)
{
    if (!meter)
        return;

    double ia = meter->ia();
    double ib = meter->ib();
    double ic = meter->ic();

    // 检查A相电流
    if (ia > m_threshold.overCurrentThreshold)
    {
        triggerAlarm(meter, AlarmType::OverCurrentA, ia, m_threshold.overCurrentThreshold);
    }
    else
    {
        QString key = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverCurrentA));
        if (m_activeAlarms.contains(key))
            recoverAlarm(key);
    }

    // 检查B相电流
    if (ib > m_threshold.overCurrentThreshold)
    {
        triggerAlarm(meter, AlarmType::OverCurrentB, ib, m_threshold.overCurrentThreshold);
    }
    else
    {
        QString key = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverCurrentB));
        if (m_activeAlarms.contains(key))
            recoverAlarm(key);
    }

    // 检查C相电流
    if (ic > m_threshold.overCurrentThreshold)
    {
        triggerAlarm(meter, AlarmType::OverCurrentC, ic, m_threshold.overCurrentThreshold);
    }
    else
    {
        QString key = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(AlarmType::OverCurrentC));
        if (m_activeAlarms.contains(key))
            recoverAlarm(key);
    }
}

void AlarmEngine::triggerAlarm(Meter *meter, AlarmType type, double value, double threshold)
{
    if (!meter)
        return;

    QString uniqueKey = QString("%1_%2").arg(meter->meterId()).arg(static_cast<int>(type));

    // 去重：如果该报警已激活，不重复触发
    if (isAlarmActive(uniqueKey))
    {
        return;
    }

    // 创建报警事件
    AlarmEvent event;
    event.alarmId = -1; // 暂时未保存到数据库
    event.meterId = meter->meterId();
    event.meterName = meter->name();
    event.type = type;
    event.typeName = getAlarmTypeName(type);
    event.value = value;
    event.threshold = threshold;
    event.timestamp = QDateTime::currentDateTime();
    event.active = true;
    event.acknowledged = false;

    // 保存到数据库
    int alarmId = saveAlarmToDatabase(event);
    if (alarmId > 0)
    {
        event.alarmId = alarmId;

        // 添加到激活报警列表
        m_activeAlarms.insert(uniqueKey, event);

        // 增加总报警计数
        m_totalAlarmCount++;
        emit totalAlarmCountChanged();
        emit activeAlarmCountChanged();

        // 发送报警信号
        emit alarmTriggered(event);

        Logger::instance()->warning(QString("【报警触发】%1").arg(event.description()));
    }
}

void AlarmEngine::recoverAlarm(const QString &uniqueKey)
{
    if (!m_activeAlarms.contains(uniqueKey))
    {
        return;
    }

    AlarmEvent event = m_activeAlarms.value(uniqueKey);
    event.active = false;

    // 从激活列表中移除
    m_activeAlarms.remove(uniqueKey);
    emit activeAlarmCountChanged();

    // 发送恢复信号
    emit alarmRecovered(event.meterId, event.type);

    Logger::instance()->info(QString("【报警恢复】电表 %1 - %2")
                                 .arg(event.meterName)
                                 .arg(event.typeName));
}

bool AlarmEngine::isAlarmActive(const QString &uniqueKey) const
{
    return m_activeAlarms.contains(uniqueKey);
}

int AlarmEngine::saveAlarmToDatabase(const AlarmEvent &event)
{
    if (!m_dbManager)
    {
        Logger::instance()->error("报警引擎：数据库管理器未初始化");
        return -1;
    }

    AlarmRecord record;
    record.meterId = event.meterId;
    record.alarmType = event.typeName;
    record.alarmValue = event.value;
    record.threshold = event.threshold;
    record.timestamp = event.timestamp;
    record.acknowledged = false;

    int alarmId = m_dbManager->insertAlarmRecord(record);

    if (alarmId > 0)
    {
        emit m_dbManager->alarmRecordInserted(alarmId);
    }
    else
    {
        Logger::instance()->error(QString("保存报警记录失败：电表 %1").arg(event.meterId));
    }

    return alarmId;
}
